const express = require('express');
const formData = require('form-data');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const request = require('request');
const sql = require('./sql');
const router = express.Router();
const cfg = require('../../other/config');
const gm = require('../../other/gm');
const jslog = require('../../other/jslog');
const { execFile } = require('child_process');

router.get('/favicon.ico', function (req, res, next) {
  res.end();
});

router.get('/', function (req, res, next) {
  res.render('index', { title: 'Express' });
});

router.post('/login', function (req, res, next) {
  let whiteIp = cfg.whiteIp;
  let adminIp = cfg.admin.ip;

  let obj = {
    success: 0,
  };
  let reqInfo = req.body;
  let reqIp = req.ip;
  if (reqIp == adminIp) {
    if (reqInfo.username == cfg.admin.username
      && reqInfo.password == cfg.admin.password) {
      obj.success = 1;
      console.log("admin Login", reqIp);
    }
  } else if (-1 != whiteIp.indexOf(reqIp)) {
    obj.success = 1;
  } else if (reqIp == '::ffff:127.0.0.1') {
    obj.success = 1;
  }
  req.session.ip = reqIp;
  res.send(obj);
});

router.post('/config', function (req, res, next) {
  let obj = JSON.parse(JSON.stringify(cfg));
  let adminIp = cfg.admin.ip;
  if (adminIp != req.session.ip)
    delete obj.admin;
  res.send(obj);
});

router.post('/server', function (req, res, next) {
  let servers = cfg.servers;
  let obj = [];
  for (let i = 0; i < servers.length; ++i) {
    let server = servers[i];
    //let str = server.name + ' ip:' + server.ip + ' port:' + server.port;
    let str = server.name;
    obj.push({
      key: i + 1,
      server: str,
    });
  }
  let adminIp = cfg.admin.ip;
  if (adminIp != req.session.ip)
    obj.pop();
  res.send(obj);
});

router.post('/gm', function (req, res, next) {
  let obj = {};
  let gmObj = gm;
  for (let type in gmObj) {
    let str = type.toString() + '.' + gmObj[type].describe;
    obj[type] = str;
  }
  res.send(obj);
});

router.post('/gmContent', function (req, res, next) {
  let body = req.body;
  let type = body.type;
  let gmObj = gm;
  let content = gmObj[type];
  res.send(content);
});

router.post('/gmExec', function (req, res, next) {
  function aesEncrypt() {
    let secret = cfg.secret;
    let data = Date.now().toString();
    const cipher = crypto.createCipher('aes256', secret);
    var crypted = cipher.update(data, 'utf8', 'hex');
    crypted += cipher.final('hex');
    return crypted;
  }
  if (4 == reqInfo.requestServer) {
    let adminIp = cfg.admin.ip;
    if (adminIp != req.session.ip) {
      res.end();
      return;
    }
  }
  let reqInfo = req.body;
  let server = cfg.servers[reqInfo.requestServer - 1];
  delete reqInfo.requestServer;

  var request_url = 'http://' + server.ip + ':' + server.port;
  let form = new formData();
  let auth = aesEncrypt();
  console.log(auth);
  form.append("auth", auth);
  form.append("content", JSON.stringify(reqInfo));
  console.log(request_url, auth, reqInfo);
  form.submit(request_url, function (err, idipRes) {
    if (err)
      console.log(err);
    idipRes.on('data', function (data) {
      res.send(data);
    });
    idipRes.on('error', function (data) {
      res.send('error');
    });
    idipRes.on('end', function (data) {
      res.end();
    });
  });

});

router.post('/mysqlSelectReq', async function (req, res, next) {
  let ret = await sql.selectSql(req.body);
  res.send(ret);
});

router.post('/mysqlUpdateReq', async function (req, res, next) {
  let ret = await sql.updateSql(req.body);
  res.send(ret);
});

router.post('/sqlExecReq', async function (req, res, next) {
  let ret = await sql.sqlExec(req.body);
  res.send(ret);
});

router.post('/jsLog', function (req, res, next) {
  let obj = {};
  for (let id in jslog) {
    let lObj = jslog[id];
    if (!lObj.id)
      continue;
    let str = lObj.id.toString() + '.' + lObj.describe + ' ' + lObj.logType;
    obj[id] = str;
  }
  res.send(obj);
});

router.post('/jsLogExec', async function (req, res, next) {
  var dayStartTm = function (time) {
    time = time || 0;
    let date = new Date(time);
    let ts = date.getTime();
    return ts;
  }
  let reqInfo = req.body;
  let startTm = dayStartTm(reqInfo.startTm);
  let endTm = dayStartTm(reqInfo.endTm);
  if (startTm >= endTm)
    return res.send("date params error");
  let id = Number(reqInfo.key);
  let params = reqInfo.params.split(';');

  let filePath = path.join(__dirname, "./fileHandler.js");
  execFile('node', [filePath, id, startTm, endTm, params], (error, stdout, stderr) => {
    if (error) {
      console.log(error);
      res.end();
      return;
    }
    //res.send(JSON.parse(stdout));
    res.send(stdout);
  });
});

router.post('/jsModuleInfo', function (req, res, next) {
  let ret = {};
  let dirPath = path.join(__dirname, "../../other/jsModule");
  let files = fs.readdirSync(dirPath);
  let idx = 0;
  for (let file of files) {
    let filePath = path.join(dirPath, file);
    //let prefix = filePath.slice(0, filePath.length - 3);
    let suffix = filePath.slice(filePath.length - 3, filePath.length);
    if (suffix != '.js')
      continue;
    let stats = fs.lstatSync(filePath);
    if (stats.isDirectory())
      continue;
    ret[++idx] = file;
  }
  res.send(ret);
});

router.post('/jsModuleParam', function (req, res, next) {
  let fileName = req.body.fileName;
  if (!fileName) {
    res.send("no fileName");
    return;
  }

  let filePath = path.join(__dirname, "../../other/jsModule", fileName);
  let ret = {
    __execFileName: fileName,
    ip: '',
    port: 0,
  };
  let tObj = require(filePath);
  Object.assign(ret, tObj);
  res.send(ret);
});

router.post('/jsModuleExec', function (req, res, next) {
  let reqInfo = req.body;
  let execFileName = reqInfo.__execFileName;
  let ip = reqInfo.ip;
  let port = reqInfo.port;
  delete reqInfo.ip;
  delete reqInfo.port;

  let fileName = path.join(__dirname, "../../other/jsModule", execFileName);
  if (!ip || !port) {
    delete reqInfo.__execFileName;
    execFile('node', [fileName, JSON.stringify(reqInfo)], (error, stdout, stderr) => {
      if (error) {
        console.log(error);
        res.end();
        return;
      }
      res.send(stdout);
    });
  } else {
    const url = 'http://' + ip + ':' + port + '/jsModuleExec';
    request.post({
      url: url,
      form: reqInfo,
    }, function(err, httpRes, body) {
      if (err) {
        console.log(err);
        res.end();
        return;
      }
      res.send(body);
    });
  }
});

module.exports = router;
